package com.liumingtai.learn.shiro.config.shiro;

import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONObject;
import com.liumingtai.learn.shiro.module.test01.entity.BlogUser;
import com.liumingtai.learn.shiro.utils.R;
import com.liumingtai.learn.shiro.utils.RedisUtil;
import com.liumingtai.learn.shiro.utils.TokenUtil;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class TokenFilter extends BasicHttpAuthenticationFilter {

    /**
     * 过滤方法
     */
    protected boolean isAccessAllowed(ServletRequest request,
                                      ServletResponse response, Object object) {
        String token = ((HttpServletRequest) request).getHeader("token");
        R jsonResult = new R();
        //判断请求的请求头是否带上 "Token"
        if (token != null) {
            try {
                //token解析得到 username+password 触发登录方法
                /*    AesToken m = new AesToken(token);
                 */
            /*    BlogUser user = Convert.convert(new TypeReference<BlogUser>() {
                },TokenUtil.parseToken(token));*/

                //先去 redis 查找这个token存不存在 不存在说明过期
                Object shiroToken1 = redisUtil.hGet("shiroToken", token);
                if (shiroToken1 == null) {
                    throw new org.apache.shiro.authc.AuthenticationException("token过期");
                }
                BlogUser user = Convert.convert(BlogUser.class, TokenUtil.parseToken(token));
                AuthenticationToken shiroToken = new UsernamePasswordToken(user.getUserName(), user.getPassword());
                getSubject(request, response).login(shiroToken);
                return true;
            } catch (org.apache.shiro.authc.AuthenticationException e) {
                //token 错误
                e.printStackTrace();
                JSONObject jsonObject = new JSONObject(jsonResult);
                jsonObject.set("code", 401);
                jsonObject.set("msg", "token错误,或token已过期");
                responseOutWithJson(response, jsonObject);
                return false;
            }
        }
        //如果请求头不存在 Token，则可能是执行登陆操作或者是游客状态访问，无需检查 token，直接返回 true
        return true;
    }

    /**
     * 以JSON格式输出
     *
     * @param response
     */
    protected void responseOutWithJson(ServletResponse response,
                                       Object responseObject) {
        //将实体对象转换为JSON Object转换
        //   JSONObject responseJSONObject = JSONObject.fromObject(responseObject);
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = httpServletResponse.getWriter();
            out.append((String) responseObject);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}
